#region Copyright
//Copyright 2008 PivDev

//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at

//   http://www.apache.org/licenses/LICENSE-2.0

//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License. 
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Collections;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace CRMAddin
{
    [RunInstaller(true)]
    public partial class CRMAddingInstaller : Installer
    {
        private const string ExtNameSpace =
          "http://schemas.microsoft.com/AutomationExtensibility";

        /// <summary>
        /// Constructor. Initializes components.
        /// </summary>

        public CRMAddingInstaller()
            : base()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Overrides Installer.Install,
        /// which will be executed during install process.
        /// </summary>
        /// <param name="savedState">The saved state.</param>

        public override void Install(IDictionary savedState)
        {
            // Uncomment the following line, recompile the setup
            // project and run the setup executable if you want
            // to debug into this custom action.

            //          Debugger.Break();


            base.Install(savedState);

            // Parameters required to pass in from installer

            string productName = this.Context.Parameters["ProductName"];
            string assemblyName = this.Context.Parameters["AssemblyName"];

            // Setup .addin path and assembly path

            string addinTargetPath;
            string vs2005Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Visual Studio 2005");
            string vs2008Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Visual Studio 2008");
            string assemblyPath = Path.GetDirectoryName(
                   System.Reflection.Assembly.GetExecutingAssembly().Location);
            string addinControlFileName = assemblyName + ".Addin";
            string addinAssemblyFileName = assemblyName + ".dll";

            try
            {
                DirectoryInfo dirinfo = new DirectoryInfo(vs2005Path);
                #region Visual Studio 2005 setup
                if (dirinfo.Exists)
                {
                    addinTargetPath = Path.Combine(vs2005Path, "Addins");
                    dirinfo = new DirectoryInfo(addinTargetPath);
                    if (!dirinfo.Exists)
                    {
                        dirinfo.Create();
                    }

                    string sourceFile = Path.Combine(assemblyPath, addinControlFileName);
                    XmlDocument doc = new XmlDocument();
                    doc.Load(sourceFile);
                    XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);
                    xnm.AddNamespace("def", ExtNameSpace);

                    // Update Addin/Assembly node

                    XmlNode node = doc.SelectSingleNode("/def:" +
                        "Extensibility/def:Addin/def:Assembly", xnm);
                    if (node != null)
                    {
                        node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
                    }

                    // Update ToolsOptionsPage/Assembly node

                    node = doc.SelectSingleNode("/def:Extensibility/def:" +
                           "ToolsOptionsPage/def:Category/def:SubCategory/def:Assembly", xnm);
                    if (node != null)
                    {
                        node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
                    }

                    doc.Save(sourceFile);

                    string targetFile = Path.Combine(addinTargetPath, addinControlFileName);
                    File.Copy(sourceFile, targetFile, true);

                    // Save AddinPath to be used in Uninstall or Rollback

                    savedState.Add("AddinPath2005", targetFile);
                } 
                #endregion

                #region Visual Studio 2008 setup
                dirinfo = new DirectoryInfo(vs2008Path);
                if (dirinfo.Exists)
                {
                    addinTargetPath = Path.Combine(vs2008Path, "Addins");
                    dirinfo = new DirectoryInfo(addinTargetPath);
                    if (!dirinfo.Exists)
                    {
                        dirinfo.Create();
                    }

                    string sourceFile = Path.Combine(assemblyPath, addinControlFileName);
                    XmlDocument doc = new XmlDocument();
                    doc.Load(sourceFile);
                    XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);
                    xnm.AddNamespace("def", ExtNameSpace);

                    // Update Addin/Assembly node

                    XmlNode node = doc.SelectSingleNode("/def:" +
                        "Extensibility/def:Addin/def:Assembly", xnm);
                    if (node != null)
                    {
                        node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
                    }

                    // Update ToolsOptionsPage/Assembly node

                    node = doc.SelectSingleNode("/def:Extensibility/def:" +
                           "ToolsOptionsPage/def:Category/def:SubCategory/def:Assembly", xnm);
                    if (node != null)
                    {
                        node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
                    }

                    doc.Save(sourceFile);

                    string targetFile = Path.Combine(addinTargetPath, addinControlFileName);
                    File.Copy(sourceFile, targetFile, true);

                    // Save AddinPath to be used in Uninstall or Rollback

                    savedState.Add("AddinPath2008", targetFile);
                } 
                #endregion


            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }

        /// <summary>
        /// Overrides Installer.Rollback, which will be executed during rollback process.
        /// </summary>

        /// <param name="savedState">The saved state.</param>

        public override void Rollback(IDictionary savedState)
        {
            ////Debugger.Break();

            base.Rollback(savedState);

            try
            {
                string fileName = (string)savedState["AddinPath2005"];
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                fileName = (string)savedState["AddinPath2008"];
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }

        /// <summary>
        /// Overrides Installer.Uninstall, which will be executed during uninstall process.
        /// </summary>

        /// <param name="savedState">The saved state.</param>

        public override void Uninstall(IDictionary savedState)
        {
            ////Debugger.Break();

            base.Uninstall(savedState);

            try
            {
                string fileName = (string)savedState["AddinPath2005"];
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                fileName = (string)savedState["AddinPath2008"];
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }
    }
}